from PyQt6.QtGui import QIcon, QFont, QFontDatabase, QPainter, QColor
from PyQt6.QtCore import QSize, Qt
import os
import requests
import zipfile
import io
from typing import Optional, Dict, Tuple


class IconManager:
    """Iconfont 图标资源管理类，负责加载和管理图标资源"""
    
    def __init__(self, resources_dir: str = "resources"):
        """
        初始化图标管理器
        
        Args:
            resources_dir: 图标资源目录
        """
        self.resources_dir = resources_dir
        self.font_id = -1
        self.icon_map: Dict[str, str] = {}
        
        # 确保资源目录存在
        os.makedirs(resources_dir, exist_ok=True)
        
        # 尝试加载图标字体
        font_path = os.path.join(resources_dir, "iconfont.ttf")
        if os.path.exists(font_path):
            self.load_icon_font(font_path)
    
    def load_icon_font(self, font_file_path: str) -> bool:
        """
        加载图标字体文件
        
        Args:
            font_file_path: 字体文件路径
            
        Returns:
            是否成功加载
        """
        try:
            # 加载字体到Qt字体数据库
            self.font_id = QFontDatabase.addApplicationFont(font_file_path)
            if self.font_id == -1:
                print("无法加载图标字体文件")
                return False
            
            # 尝试加载图标映射
            css_path = os.path.join(os.path.dirname(font_file_path), "iconfont.css")
            if os.path.exists(css_path):
                self._parse_css_file(css_path)
            
            return True
        except Exception as e:
            print(f"加载图标字体错误: {str(e)}")
            return False
    
    def _parse_css_file(self, css_path: str) -> None:
        """
        解析CSS文件以提取图标名称和Unicode映射
        
        Args:
            css_path: CSS文件路径
        """
        try:
            with open(css_path, 'r', encoding='utf-8') as f:
                css_content = f.read()
            
            # 提取图标名称和Unicode
            import re
            pattern = r'\.icon-([^:]+):before\s*{\s*content:\s*"\\([^"]+)"'
            matches = re.findall(pattern, css_content)
            
            for name, code in matches:
                self.icon_map[name] = code
                
        except Exception as e:
            print(f"解析CSS文件错误: {str(e)}")
    
    def get_icon(self, icon_name: str, color: Optional[QColor] = None, size: Optional[QSize] = None) -> QIcon:
        """
        获取指定图标的QIcon对象
        
        Args:
            icon_name: 图标名称
            color: 图标颜色
            size: 图标大小
            
        Returns:
            QIcon对象
        """
        if self.font_id == -1:
            # 返回一个空图标
            return QIcon()
        
        if size is None:
            size = QSize(24, 24)
            
        if color is None:
            color = QColor(51, 51, 51)  # 默认深灰色
        
        # 创建图标
        icon = QIcon()
        
        # 从字体创建图标
        font_families = QFontDatabase.applicationFontFamilies(self.font_id)
        if not font_families:
            return QIcon()
        
        font = QFont(font_families[0])
        font.setPixelSize(size.height())
        
        unicode_char = self._get_unicode_char(icon_name)
        if not unicode_char:
            return QIcon()
        
        # 使用QPainter创建图标
        from PyQt6.QtGui import QPixmap
        pixmap = QPixmap(size)
        pixmap.fill(Qt.GlobalColor.transparent)
        
        painter = QPainter(pixmap)
        painter.setFont(font)
        painter.setPen(color)
        painter.drawText(pixmap.rect(), Qt.AlignmentFlag.AlignCenter, unicode_char)
        painter.end()
        
        icon.addPixmap(pixmap)
        return icon
    
    def _get_unicode_char(self, icon_name: str) -> str:
        """
        根据图标名称获取Unicode字符
        
        Args:
            icon_name: 图标名称
            
        Returns:
            Unicode字符
        """
        if icon_name in self.icon_map:
            # 转换为Unicode字符
            return chr(int(self.icon_map[icon_name], 16))
        
        return ""
    
    def download_icon_font(self, project_id: str, token: str) -> bool:
        """
        从Iconfont下载图标字体资源
        
        Args:
            project_id: Iconfont项目ID
            token: 访问令牌
            
        Returns:
            是否成功下载
        """
        try:
            # 构建下载URL
            url = f"https://www.iconfont.cn/api/project/download.zip?pid={project_id}&token={token}"
            
            # 下载字体包
            response = requests.get(url)
            if response.status_code != 200:
                print(f"下载图标字体失败: HTTP状态码 {response.status_code}")
                return False
            
            # 解压字体包
            with zipfile.ZipFile(io.BytesIO(response.content)) as z:
                # 提取需要的文件
                for file_name in z.namelist():
                    if file_name.endswith('.ttf') or file_name.endswith('.css'):
                        with open(os.path.join(self.resources_dir, os.path.basename(file_name)), 'wb') as f:
                            f.write(z.read(file_name))
            
            # 加载下载的字体
            return self.load_icon_font(os.path.join(self.resources_dir, "iconfont.ttf"))
            
        except Exception as e:
            print(f"下载图标字体错误: {str(e)}")
            return False 